package alibobo.util.io.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;



public class FileUtils {

	// public static String readFileAsString(String filePath) throws
	// java.io.IOException {
	// byte[] buffer = new byte[(int) new File(filePath).length()];
	// BufferedInputStream f = new BufferedInputStream(new
	// FileInputStream(filePath));
	// f.read(buffer);
	// return new String(buffer);
	// }

	/*****************************************************************************************************************
	 * 
	 * @param path
	 * @throws IOException
	 *****************************************************************************************************************/
	public static void saveStringListToFile(String fileName, String prefix,
			List<String> content, String seg, String postFix)
			throws IOException {
		StringBuilder sb = new StringBuilder();
		sb.append(prefix);
		for (String s : content) {
			sb.append(s);
			sb.append(seg);
		}
		sb.append(postFix);
		writeStringToFile(sb.toString(), fileName);
	}

	/*****************************************************************************************************************
	 * 
	 * @param path
	 *****************************************************************************************************************/
	public static void deleteDirectory(File path) {
		try {

			if (path.exists()) {
				File[] files = path.listFiles();
				for (int i = 0; i < files.length; i++) {
					if (files[i].isDirectory()) {
						deleteDirectory(files[i]);
					} else {
						files[i].delete();
					}
				}
			}
			path.delete();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	public static List<File> getFileListing(File aStartingDir)
			throws FileNotFoundException {
		validateDirectory(aStartingDir);
		List<File> result = getFileListingNoSort(aStartingDir);
		Collections.sort(result);
		return result;
	}

	static private void validateDirectory(File aDirectory)
			throws FileNotFoundException {
		if (aDirectory == null) {
			throw new IllegalArgumentException("Directory should not be null.");
		}
		if (!aDirectory.exists()) {
			throw new FileNotFoundException("Directory does not exist: "
					+ aDirectory);
		}
		if (!aDirectory.isDirectory()) {
			throw new IllegalArgumentException("Is not a directory: "
					+ aDirectory);
		}
		if (!aDirectory.canRead()) {
			throw new IllegalArgumentException("Directory cannot be read: "
					+ aDirectory);
		}
	}

	protected static List<File> getFileListingNoSort(File aStartingDir)
			throws FileNotFoundException {
		List<File> result = new ArrayList<File>();
		File[] filesAndDirs = aStartingDir.listFiles();
		List<File> filesDirs = Arrays.asList(filesAndDirs);
		for (File file : filesDirs) {
			if (file.isDirectory() == false)
				result.add(file); // always add, even if directory
			if (!file.isFile()) {
				// must be a directory
				// recursive call!
				List<File> deeperList = getFileListingNoSort(file);
				result.addAll(deeperList);
			}
		}
		return result;
	}

	public static String readFileAsString(String filePath)
			throws java.io.IOException {

		InputStreamReader read = new InputStreamReader(new FileInputStream(
				filePath));
		BufferedReader reader = new BufferedReader(read);
		StringBuilder sb = new StringBuilder();
		String line;
		sb.append("");
		while ((line = reader.readLine()) != null) {
			sb.append(line);
			sb.append("\n");
		}
		reader.close();
		read.close();
		return sb.toString().trim();
	}

	public static void writeStringToFile(String string, String fileName)
			throws java.io.IOException {

		BufferedWriter out;
		out = new BufferedWriter(new FileWriter(fileName));
		out.write(string);
		out.close();
	}

	public static void writeStringToFile(String string, String fileName,
			boolean append) throws java.io.IOException {

		BufferedWriter out;
		out = new BufferedWriter(new FileWriter(fileName, append));
		out.write(string);
		out.close();
	}

	public static void writeStringsToFile(List<String> ss, String fileName)
			throws IOException {
		StringBuffer sb = new StringBuffer();
		int sz = ss.size();
		for (int i = 0; i < sz; i++) {
			String s = ss.get(i);
			if (StringUtils.isBlank(s))
				continue;
			sb.append(s);
			if (i < sz - 1)
				sb.append("\r\n");
		}

		writeStringToFile(sb.toString(), fileName);

	}

	public static void writeStringToFile(String content, String fileName,
			String encode) {
		BufferedWriter bw;
		try {
			File file = new File(fileName);
			// bw = new BufferedWriter(new FileWriter(file, false));
			bw = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(file), encode));
			bw.write(content);
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static void writeFileToOutputStream(String fileName,
			OutputStream streamOut) {

		byte[] buff = new byte[65536];
		FileInputStream streamIn = null;
		try {
			streamIn = new FileInputStream(fileName);
			int c;
			while ((c = streamIn.read(buff, 0, 65536)) != -1) {
				streamOut.write(buff, 0, c);
			}

		} catch (Exception e) {

			e.printStackTrace();
		} finally {
			try {
				streamIn.close();
			} catch (Exception e) {

			}
		}

	}

	public static String getName(String fileName) {
		int pos1, pos2, pos;
		pos1 = fileName.lastIndexOf("/");
		pos2 = fileName.lastIndexOf("\\");
		pos = pos1 > pos2 ? pos1 : pos2;
		if (pos < 0)
			return fileName;
		return fileName.substring(pos + 1);
	}

	public static boolean mkdirs(String pathName) {
		File f = new File(pathName);
		return f.mkdirs();

	}

	public static String getDirectory(String fileName) {
		File f = new File(fileName);
		if (f.exists() == false)
			return null;
		if (f.isDirectory())
			return fileName;
		return f.getParent();
	}

	public static boolean mkdirForFile(String fileName) {
		File f = new File(fileName);
		String p = f.getParent();
		File pf = new File(p);
		return pf.mkdirs();
	}

	public static String getClassPath(Class t) {
		URL url = t.getResource("/");
		return url.getPath();
	}

	public void getFiles() {

	}

	public static List<String> readLines(String fileName) {

		List<String> result = new ArrayList<String>();
		try {
			InputStreamReader read = new InputStreamReader(new FileInputStream(
					fileName));
			BufferedReader reader = new BufferedReader(read);
			StringBuilder sb = new StringBuilder();
			String line;

			while ((line = reader.readLine()) != null) {
				result.add(line);
			}
			reader.close();
			read.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
		return result;

	}

	@Deprecated
	public static List<String> readLinesANSI(String fileName) {

		List<String> result = new ArrayList<String>();
		try {

			String content = readFileAsString(fileName);
			String[] ss = content.split("\r\n");
			for (String s : ss) {
				result.add(s);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	public static boolean exist(String fileName) {
		File f = new File(fileName);
		return f.exists();
	}

	public static void delete(String fileName) {
		File f = new File(fileName);
		f.delete();
	}
}
